#include <hardware.h>
#include <delay.h>
#include <viniSPI.h>
#include <lcd.h>

extern volatile unsigned char converting;
extern volatile unsigned char full_messages;
extern volatile unsigned char lcd_present;
unsigned char admux_setting[] = {ADC_VREF_AVCC, ADC_VREF_AVCC, ADC_VREF_AVCC, ADC_VREF_AVCC, ADC_VREF_AVCC, ADC_VREF_AVCC, ADC_VREF_AVCC, ADC_VREF_AVCC};
static unsigned char input_index = 0;

// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
static unsigned char adc_data[] = {0, 0, 0, 0, 0, 0, 0, 0};
static unsigned char adc_count = 0;
admux_setting[ADC_05P0D5] = ADC_VREF_INTL;

converting = 1;

if (adc_data[input_index] < ADCH)
    {
    adc_data[input_index] = ADCH;
    }

if (adc_count > 48)
    {
    char2buffer(adc_data[input_index]);
    adc_data[input_index] = 0;
    }

//if ((full_messages == 1) && (input_index > 1))
//    {
//    display_value(adc_data[input_index]); // Display as a number not with ASCII

//    if (lcd_present == 1)
//        {
//        lcd_putchar('-');
//        }
//    }

//else
//    {
//    char2buffer(adc_data[input_index]);
//    }

if (++input_index > (LAST_ADC_INPUT))
    {         
//    if (full_messages == 1)
//        {
//        strf2buffer("\r");
//        }

    if (adc_data[ADC_03P0D1] > 156)
        { 
        lithium_recharge(adc_data[ADC_03P0D1]);
        }

    if (++adc_count > 49) // each second
        {
        adc_count = 0;
        strf2buffer("\r");
        converting = 0;
        }
        
    input_index = 0;
    ADMUX = admux_setting[0];
    delay_ms(19); // open loop sample rate 50 Hz
    ADCSRA|= 0x40; // Start Next ADC Conversion  
    }            

else
    {                                         
    ADMUX = admux_setting[input_index] + input_index;
    delay_us(100); // required for noise suppression 0.5 ms
    ADCSRA|= 0x40; // Start Next ADC Conversion
    }
}                                                                    

// Timer 1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
converting = ICR1L; // low byte read puts high byte into temp register           
TIMSK1 = 0x00; // disable input capture interrupt

if (full_messages == 1)
    {
    if (input_index == 0)
        {
        display_value(converting>>2 | ICR1H<<6);    
        }

    else
        {
        display_value(converting>>7 | ICR1H<<1);    
        }
        
    if (lcd_present == 1)
        {
        lcd_putchar('-');
        }
        
    strf2buffer("\r");
    }

else
    {
    char2buffer(converting);
    char2buffer(ICR1H);
    }
    
converting = 0;

ADMUX = admux_setting[0];
}

// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
TIMSK1 = 0x00; // disable input capture interrupt

#asm("cli")

if (full_messages == 1)
    {
    display_value(255);        

    if (lcd_present == 1)
        {
        lcd_putchar('-');
        }
        
    strf2buffer("\r");
    }

else
    {
    char2buffer(255);
    char2buffer(255);
    }
    
converting = 0;

ADMUX = admux_setting[0];
}

void comparator_stopwatch0(unsigned char channel)
{
input_index = channel;
converting = 1;

ADMUX = ADC_VREF_AVCC + channel;
ADCSRA = 0x0B; // Disable ADC

TIFR1|= 0x20;            // clear input capture interrupt flag
TIMSK1 = 0x21;           // enable input capture interrupt
DDRA&= ~(0x01<<channel); // begin charging sensor
TCNT1H = 0x00;
TCNT1L = 0x00;
     
while (converting > 0)  
    {                
    }  

DDRA|= 0x01<<channel; // discharge sensor
input_index = 0;

ADCSRA = 0x8B; // Enable ADC
}

void comparator_stopwatch1(unsigned char channel)
{
input_index = channel;
converting = 1;

ADMUX = ADC_VREF_AVCC + channel;
ADCSRA = 0x0B; // Disable ADC

PORTA.1 = 1;             // charge sensor
delay_ms(1000);

TIFR1|= 0x20;            // clear input capture interrupt flag
TIMSK1 = 0x21;           // enable input capture interrupt
DDRA&= ~(0x01<<channel); // begin discharging sensor
PORTA.1 = 0;
TCNT1H = 0x00;
TCNT1L = 0x00;
     
while (converting > 0)  
    {                
    }  

DDRA|= 0x01<<channel; // discharge sensor
input_index = 0;

ADCSRA = 0x8B; // Enable ADC
}